/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.marist.cs.os.g3.processors;

import edu.marist.cs.os.g3.mos.Buffer;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.LinkedList;
import java.util.Queue;

/**
 *
 * @author Cameron
 * In regard to the "simulation, housekeeping, assign new task" cycle,
 * Each channel will implement the simulation phase.
 * This channel consumes an empty buffer and returns the buffer to put on the
 * input-full buffer queue.
 */
public class Channel1 {

    public static final int TIME_REQUIRED = 5;
    public static final int IOI_VALUE = 1;
    int timer = 0;
    Buffer buffer = new Buffer();
    boolean busy = false;
    CPU cpu;
    BufferedReader input;
    Queue<String> cardQueue = new LinkedList<>();

    public Channel1(CPU cpu, BufferedReader input) {
        try {
            this.cpu = cpu;
            this.input = input;

            //Read all "cards" (lines) from input file, add to internal "card queue"
            String card = input.readLine();
            while (card != null) {
                for (int i = 0; i < 40 - card.length(); i++) {
                    //Pad card to length 40 with spaces
                    card += " ";
                }
                cardQueue.add(card);
                card = input.readLine();
            }


            //OS starts with IOI = 1, so the first card is read immediately.
            //System.out.println(cardQueue.element());
            buffer.setData(cardQueue.remove());
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Start the Channel 1 Input Spool task.
     * @param emptyBuffer A buffer from the empty buffer queue
     * @return whether the task could be started or not
     */
    public boolean startTask(Buffer emptyBuffer) {
        if (busy) {
            return false;
        }
        buffer = emptyBuffer;
        timer = 0;
        busy = true;
        return true;
    }
    //@overload

    public boolean startTask() {
        if (busy) {
            return false;
        }
        timer = 0;
        busy = true;
        return true;
    }

    /**
     * Increase the timer if a task is in progress.
     */
    public void cycleComplete() {
        timer++;
        if (busy && timer == Channel1.TIME_REQUIRED) {
            //Complete simulation
            if (!cardQueue.isEmpty()) {
                buffer.setData(cardQueue.remove());
            }
            cpu.IOI += Channel1.IOI_VALUE;
            busy = false;
        }

    }

    /**
     * Get the buffer Channel 1 worked on
     * @return The buffer Channel 1 worked on 
     */
    public Buffer getBuffer() {
        return buffer;
    }

    /**
     * Get the value of the timer.
     * @return the value of the timer
     */
    public int getTimer() {
        return timer;
    }

    /**
     * Check to see if we've reached the end of the input file
     * @return whether the last card has been processed
     */
    public boolean eof() {
        return cardQueue.isEmpty();
    }

    public boolean isBusy() {
        return busy;
    }
}
